var DEBUG = true;

// 定数の宣言
// DB Access
var DB_NAME = 'rmb48_test';
var DB_USER = 'db_user';
var DB_PASS = 'db_user';
var USER_TABLE_NAME = 'User';
// Twitter Access
var TWITTER_HOST = 'api.twitter.com';
var TWITTER_ADDRESS = '/1/statuses/user_timeline.json';
// Yahoo! API
var Y_APP_ID = '2q8Yb2Wxg6512M1iab0Apa576G7UgO1.PKuPtdf7HlnuOsGfQmDWqvEMKpTjYA--';
var Y_HOST = 'jlp.yahooapis.jp';
var Y_PARSE_ADDRESS = '/MAService/V1/parse';
var Y_EXTRACT_ADDRESS = '/KeyphraseService/V1/extract';



// Twitter監視クラス（コンストラクタ）
//
// user_id TwitterのユーザID(screen_name) 
// interval 各ユーザのTweetを監視する間隔（ミリ秒）
// callback Tweet取得時に呼び出すメソッド
//          （callback({user:Twitterのユーザid,
//                      keywords:[単語１,単語２, ...],
//			time:経過ミリ秒}))

exports.TweetWatcher = function(user_id, interval, callback){

	//メンバ変数の設定
	this.user_id = user_id;
	this.interval = interval;
	this.callback = callback;
	
	//MySQLデータベースへの接続
	var Client = require('mysql').Client; 
	this.client = new Client();
	this.client.database = DB_NAME;
	this.client.user = DB_USER;
	this.client.password = DB_PASS;
	this.client.connect(function(err){
		if(err) console.log("ERR: " + err);
	});

	//twitter接続用のHTTPアクセスオブジェクトの準備
	this.twitterClient = require('http').createClient(80, TWITTER_HOST);
	this.yapiClient = require('http').createClient(80, Y_HOST);
};


// Tweet監視を開始
exports.TweetWatcher.prototype.startWatching = function(){
	var _this = this;
	if(DEBUG)console.log('start watching.');
	_this.getUsers();
	this.scheduledAction = setInterval(
		function(){
			//定期的に実行する監視処理
			//（query、request.on　など、コールバックで結果を返す関数の扱いが
			//　よく分からないので、再帰的に処理を実行。なおしたい。）
			var users = _this.getUsers(); 

},
		this.interval);
};

//監視対象のユーザ一覧をDBから取得
exports.TweetWatcher.prototype.getUsers = function(){

	if(DEBUG)console.log('getUsers called');
	
	var _this = this;
	this.client.query('select * from ' + USER_TABLE_NAME, function(err, result, fields){
		rtnx = err ? [] : result;
		_this.getTweets(rtnx); //ユーザごとのtweetを取得
	});
}

//ユーザごとのtweetをTwitterAPIへのHTTPリクエストにより取得
exports.TweetWatcher.prototype.getTweets = function(users){

	if(DEBUG)console.log('getTweets called users are...');
	if(DEBUG)console.log(users);


	var _this = this;

	for(var i=0; i<users.length; i++){
		//リクエスト先URLの設定。
		//取得済み最新tweetより新しいtweetを取得するため、since_idは、最新id+10を設定する。
		var requestAddress = TWITTER_ADDRESS + 
			"?screen_name=" + users[i].twitter_id + "&since_id=" + (eval(users[i].last_tweet_id) + 10);

		//console.log("DEBUG: REQUEST\n" + requestAddress);

		var request = this.twitterClient.request(
			'GET', requestAddress,
			{'host': TWITTER_HOST}
		);
		request.on('response', function(response){

			//レスポンスがchunk形式で返ってくるので順次結合
			var resultString = "";
			response.on('data', function(chunk){
				resultString += chunk;
			});
			response.on('end', function(data){
				//JSONで返されるtweet一覧のパース
				resultObject = JSON.parse(resultString);
				if(DEBUG)console.log('Twitter Result:');
				if(DEBUG)console.log(resultString);

				//tweetが有った場合の処理
				if(resultObject.length > 0){
					
					//最大tweet番号（id_str）の算出
					var max_id = 1;
					for(var j=0; j<resultObject.length; j++){
						//console.log(resultObject[j]);
						var current_id = eval(resultObject[j].id_str);
						//console.log(parseInt(resultObject[j].id_str));
						max_id = current_id > max_id ? current_id : max_id;
					}
					//最大tweet番号をDBに登録
					_this.client.query(
						'update ' + USER_TABLE_NAME + ' set last_tweet_id = \'' + max_id + '\''
						+ 'where twitter_id=\'' + resultObject[0].user.screen_name + '\';', 
						function(err, result, fields){
							if(err){console.log(result)};
					});
					
					for(var j=0; j<resultObject.length; j++){

						_this.extractNoun(resultObject[j].user.screen_name, resultObject[j].text);
					}
					
				}
			});
		});
		request.end();
	}
}

//形態素解析を実施
exports.TweetWatcher.prototype.extractNoun = function(user, text){

	//リクエスト先URLの設定。
	//取得済み最新tweetより新しいtweetを取得するため、since_idは、最新id+10を設定する。
	var requestAddress = Y_PARSE_ADDRESS + 
		"?appid=" +  Y_APP_ID  + "&output=json&callback=dummy&results=ma,uniq&uniq_filter=9|10&sentence=" +
		encodeURI(text);
	
	//console.log(requestAddress);

	//console.log("DEBUG: REQUEST\n" + requestAddress);

	var request = this.yapiClient.request(
		'GET', requestAddress,
		{'host': Y_HOST}
	);
	
	//console.log(request);

	var _this = this;
	request.on('response', function(response){

		//レスポンスがchunk形式で返ってくるので順次結合
		var resultString = "";
		response.on('data', function(chunk){
			resultString += chunk;
		});
		response.on('end', function(data){
			//console.log('DEBUG: YAP\n');
			//XMLのパース方法がよく分からないので正規表現でごり押し。なおしたい。
			var xml2js = new (require('xml2js').Parser)();
			var nouns = resultString.match(/<surface>[^<]+<\/surface><reading\/><pos>名詞<\/pos>/g);
			for(var i=0; i<nouns.length; i++){
				nouns[i] = nouns[i].replace('<pos>名詞</pos>', '').replace(/<[^>]+>/g, '');
			}
			_this.callback({id:user, keywords:nouns, time:(new Date()).getTime()});
		});
	});
	request.end();
}

//監視の中断
exports.TweetWatcher.prototype.stopWatching = function(){
	if(this.scheduledAction){
		clearInterval(this.scheduledAction);
	}
};
